/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.example.mediaplayerdemo;

import com.example.mediaplayerdemo.widget.InputDialog;
import com.ryan.ohos.extension.util.WindowUtil;
import com.ryan.ohos.extension.widget.Toast;
import com.ryan.ohos.extension.widget.toolbar.Toolbar;
import net.protyposis.ohos.mediaplayer.LogUtil;
import net.protyposis.ohos.mediaplayer.MediaSource;
import net.protyposis.ohos.mediaplayer.dash.DashSource;
import ohos.aafwk.ability.Ability;
import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.content.Intent;
import ohos.aafwk.content.Operation;
import ohos.agp.components.Button;
import ohos.agp.components.Text;
import ohos.agp.utils.Color;
import ohos.utils.PacMap;
import ohos.utils.net.Uri;

import java.io.FileDescriptor;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * MainAbility
 */
public class MainAbility extends Ability {

    private static final String TAG = MainAbility.class.getSimpleName();

    private static final int REQUEST_LOAD_VIDEO = 1;

    private Button mVideoSelectButton;
    private Button mVideoSelect2Button;
    private Button mVideoViewButton;
//    private Button mSideBySideButton;
//    private Button mSideBySideSeekTestButton;

    private Text mVideoUriText;
    private Color mVideoUriTextColor;
    private Uri mVideoUri;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_main);

        WindowUtil.hideStatusBar(getWindow(), true);

        Toolbar toolbar = (Toolbar) findComponentById(ResourceTable.Id_nav);
        toolbar.setTitle(getString(ResourceTable.String_app_name));
        toolbar.setContentInsetStartWithNavigation(0);

        mVideoSelectButton = (Button) findComponentById(ResourceTable.Id_videoselect);
        mVideoSelect2Button = (Button) findComponentById(ResourceTable.Id_videoselect2);
        mVideoViewButton = (Button) findComponentById(ResourceTable.Id_videoview);
//        mSideBySideButton = (Button) findComponentById(ResourceTable.Id_sidebyside);
//        mSideBySideSeekTestButton = (Button) findComponentById(ResourceTable.Id_sidebysideseektest);
        mVideoUriText = (Text) findComponentById(ResourceTable.Id_videouri);
        mVideoUriTextColor = mVideoUriText.getTextColor();

        setClickListener();
        versionInfos();

        Uri uri = null;
        String savedUriString = DBUtils.getInstance()
                .getString("video", "lastUri");
        if(!"".equals(savedUriString)) {
            uri = Uri.parse(savedUriString);
        }

        updateUri(uri);
    }

    @Override
    public void onSaveAbilityState(PacMap outState) {
        if (mVideoUri != null) outState.putString("uri", mVideoUri.toString());
        super.onSaveAbilityState(outState);
    }

    private void setClickListener() {

        mVideoSelectButton.setClickedListener(component -> {
            Intent intent = new Intent();
            intent.setAction("android.intent.action.OPEN_DOCUMENT");
            intent.setType("*/*");
            intent.setParam("android.intent.extra.MIME_TYPES", new String[]{"video/*", "audio/*"});
            intent.addFlags(Intent.FLAG_NOT_OHOS_COMPONENT);
            startAbilityForResult(intent, REQUEST_LOAD_VIDEO);
        });

        mVideoSelect2Button.setClickedListener(l -> {
            InputDialog dialog = new InputDialog(getContext());
            dialog.setCallback(this::onUriSelected);
            dialog.show();
        });

        mVideoViewButton.setClickedListener(component -> {
            Intent intent = new Intent();
            intent.setUri(mVideoUri);

            Operation operation = new Intent.OperationBuilder()
                    .withBundleName(getBundleName())
                    .withAbilityName(VideoViewAbility.class.getCanonicalName())
                    .build();
            intent.setOperation(operation);

            startAbility(intent);
        });

        findComponentById(ResourceTable.Id_licenses).setClickedListener(l -> {

            Intent intent = new Intent();
            intent.setParam("url", false);
            intent.setParam("title", getString(ResourceTable.String_open_source_licenses));

            Operation operation = new Intent.OperationBuilder()
                    .withBundleName(getBundleName())
                    .withAbilityName(WebAbility.class.getCanonicalName())
                    .build();
            intent.setOperation(operation);

            startAbility(intent);
        });
        findComponentById(ResourceTable.Id_privacy).setClickedListener(l -> {
            Intent intent = new Intent();
            intent.setParam("url", true);
            intent.setParam("title", getString(ResourceTable.String_privacy_policy));

            Operation operation = new Intent.OperationBuilder()
                    .withBundleName(getBundleName())
                    .withAbilityName(WebAbility.class.getCanonicalName())
                    .build();
            intent.setOperation(operation);

            startAbility(intent);
        });
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    private void onUriSelected(String url) {
        Uri uri = null;
        try {
            uri = Uri.parse(url);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if(!updateUri(uri)) {
            Toast.show(getContext(), "Invalid media URL");
        }
    }

    private boolean updateUri(final Uri uri) {
        if(uri == null) {
            mVideoUriText.setText(getString(ResourceTable.String_uri_missing));

            mVideoViewButton.setEnabled(false);
//            mSideBySideButton.setEnabled(false);
//            mSideBySideSeekTestButton.setEnabled(false);
            return false;
        } else {
            updateUri(null); // disable buttons

            // Validate content URI
            try {
                if (uri.getScheme().equals("dataability")) {
                    DataAbilityHelper helper = DataAbilityHelper.creator(getContext());
                    FileDescriptor fd = helper.openFile(uri, "r");
                }
            } catch (Exception e) {
                // The content URI is invalid, probably because the file has been removed
                // or the system rebooted (which invalidates content URIs),
                // or the uri does not contain a scheme
                return false;
            }


            mVideoUriText.setText("Loading...");

            Utils.uriToMediaSourceAsync(this, uri, new Utils.MediaSourceAsyncCallbackHandler() {
                @Override
                public void onMediaSourceLoaded(MediaSource mediaSource) {
                    String text = uri.toString();
                    if (mediaSource instanceof DashSource) {
                        text = "DASH: " + text;
                    }
                    mVideoUriText.setText(text);
                    mVideoUriText.setTextColor(mVideoUriTextColor);
                    mVideoUri = uri;

                    mVideoViewButton.setEnabled(true);
//                    mSideBySideButton.setEnabled(!(mediaSource instanceof DashSource));
//                    mSideBySideSeekTestButton.setEnabled(true);

                    DBUtils.getInstance().putString("video", "lastUri", uri.toString());
                }

                @Override
                public void onException(Exception e) {
                    mVideoUriText.setText("Error loading video" + (e.getMessage() != null ? ": " + e.getMessage() : " :("));
                    mVideoUriText.setTextColor(Color.RED);
                    LogUtil.loge(TAG, "Error loading video" + e.getCause());
                }
            });
        }

        return true;
    }

    @Override
    protected void onAbilityResult(int requestCode, int resultCode, Intent resultData) {
        if(requestCode == REQUEST_LOAD_VIDEO) {
            LogUtil.loge(TAG, "onActivityResult REQUEST_LOAD_VIDEO");
            if (resultCode == -1) updateUri(resultData.getUri());
        } else {
            super.onAbilityResult(requestCode, resultCode, resultData);
        }
    }

    private void versionInfos() {
        String versionInfos = "";
        Map<String, Class> components = new LinkedHashMap<String, Class>();
        components.put("MediaPlayer", net.protyposis.ohos.mediaplayer.BuildConfig.class);
        components.put("MediaPlayer-DASH", net.protyposis.ohos.mediaplayer.dash.BuildConfig.class);
        components.put("MediaPlayerDemo", com.example.mediaplayerdemo.BuildConfig.class);

        Iterator<String> componentIterator = components.keySet().iterator();
        while(componentIterator.hasNext()) {
            String component = componentIterator.next();
            versionInfos += component + ":" + versionInfo(components.get(component));
            if(componentIterator.hasNext()) {
                versionInfos += ", ";
            }
        }

        ((Text) findComponentById(ResourceTable.Id_versioninfos)).setText(versionInfos);
    }

    private String versionInfo(Class buildInfo) {
        String info = "";
        try {
            info += buildInfo.getField("VERSION_NAME").get(null).toString();
            info += "/";
            info += buildInfo.getField("VERSION_CODE").get(null).toString();
            info += "/";
            info += buildInfo.getField("BUILD_TYPE").get(null).toString();
            info += buildInfo.getField("FLAVOR").get(null).toString();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        }
        return info.length() == 0 ? "n/a" : info;
    }

}
